/* 测试消息存储子服务的客户端 */
#include <gflags/gflags.h>
#include <brpc/channel.h>
#include <thread>
#include <gtest/gtest.h>
#include "logger.hpp"
#include "brpc.hpp"
#include "etcd.hpp"
#include "base.pb.h"
#include "user.pb.h"
#include "message.pb.h"
#include "utils.hpp"
#include <boost/date_time/posix_time/posix_time.hpp>

DEFINE_bool(run_mode, false, "程序的运行模式，false-调试；true-发布");
DEFINE_string(log_file, "", "发布模式下，用于指定日志的输出文件");
DEFINE_int32(log_level, 0, "发布模式下，用于指定日志输出等级");

DEFINE_string(etcd_host, "127.0.0.1:2379", "服务注册中心地址");
DEFINE_string(base_service, "/service", "服务监控根目录");
DEFINE_string(message_service, "/service/message_service", "调用的服务目录");

ChatSystem::ServiceManager::ptr service_manager;


TEST(消息存储子服务测试, 获取指定时间段的消息测试) {
    auto channel = service_manager->choose(FLAGS_message_service);
    ASSERT_TRUE(channel);

    boost::posix_time::ptime start_time = boost::posix_time::time_from_string("2025-10-01 09:00:40");
    boost::posix_time::ptime end_time = boost::posix_time::time_from_string("2025-10-03 19:00:40");

    //发起Message Rpc调用
    // 2.实例化pb中的MsgStorageService_Stub类对象；
    ChatSystem::MsgStorageService_Stub stub(channel.get());
    // 3.发起rpc请求，获取响应进行处理；
    brpc::Controller cntl;
    ChatSystem::GetHistoryMsgReq req;
    ChatSystem::GetHistoryMsgRsp rsp;

    req.set_request_id(ChatSystem::Util::uuid());
    req.set_chat_session_id("会话ID1");
    req.set_start_time(boost::posix_time::to_time_t(start_time));
    req.set_over_time(boost::posix_time::to_time_t(end_time));

    stub.GetHistoryMsg(&cntl, &req, &rsp, nullptr);
    ASSERT_FALSE(cntl.Failed());
    ASSERT_TRUE(rsp.success());

    for(int i = 0; i < rsp.msg_list().size(); ++i)
    {
        auto msg = rsp.msg_list(i);
        std::cout << "-------------------------获取指定时间段的消息---------------------------------" << std::endl;
        std::cout << msg.message_id() << std::endl;
        std::cout << msg.chat_session_id() << std::endl;
        std::cout << boost::posix_time::to_simple_string(boost::posix_time::from_time_t(msg.timestamp()))<< std::endl;
        std::cout << "user_id: "<< msg.sender().user_id() << std::endl;
        std::cout << "nickname: " << msg.sender().nickname() << std::endl;
        std::cout << "avatar: " << msg.sender().avatar() << std::endl;
        if(msg.message().message_type() == ChatSystem::MessageType::STRING)
        {
            std::cout << "文本消息：" << msg.message().string_message().content() << std::endl;
        }
        else if(msg.message().message_type() == ChatSystem::MessageType::IMAGE)
        {
            std::cout << "图片消息：" << msg.message().image_message().image_contents() << std::endl;
        }
        else if(msg.message().message_type() == ChatSystem::MessageType::FILE)
        {
            std::cout << "文件名称：" << msg.message().file_message().file_name() << std::endl;
            std::cout << "文件消息：" << msg.message().file_message().file_contents() << std::endl;
        }
        else if(msg.message().message_type() == ChatSystem::MessageType::SPEECH)
        {
            std::cout << "语音消息：" << msg.message().speech_message().speech_contents() << std::endl;
        }
        else
        {
            std::cout << "未知消息类型！" << std::endl;
        }
    }

}

TEST(消息存储子服务测试, 获取最近的N条消息的测试) 
{
    auto channel = service_manager->choose(FLAGS_message_service);
    ASSERT_TRUE(channel);

    //发起Message Rpc调用
    // 2.实例化pb中的MsgStorageService_Stub类对象；
    ChatSystem::MsgStorageService_Stub stub(channel.get());
    // 3.发起rpc请求，获取响应进行处理；
    brpc::Controller cntl;
    ChatSystem::GetRecentMsgReq req;
    ChatSystem::GetRecentMsgRsp rsp;

    req.set_request_id(ChatSystem::Util::uuid());
    req.set_chat_session_id("会话ID1");
    req.set_msg_count(3);

    stub.GetRecentMsg(&cntl, &req, &rsp, nullptr);
    ASSERT_FALSE(cntl.Failed());
    ASSERT_TRUE(rsp.success());
   
    for(int i = 0; i < rsp.msg_list().size(); ++i)
    {
        auto msg = rsp.msg_list(i);
        std::cout << "--------------------------获取最近N条消息----------------------------" << std::endl;
        std::cout << msg.message_id() << std::endl;
        std::cout << msg.chat_session_id() << std::endl;
        std::cout << boost::posix_time::to_simple_string(boost::posix_time::from_time_t(msg.timestamp()))<< std::endl;
        std::cout << "user_id: "<< msg.sender().user_id() << std::endl;
        std::cout << "nickname: " << msg.sender().nickname() << std::endl;
        std::cout << "avatar: " << msg.sender().avatar() << std::endl;
        if(msg.message().message_type() == ChatSystem::MessageType::STRING)
        {
            std::cout << "文本消息：" << msg.message().string_message().content() << std::endl;
        }
        else if(msg.message().message_type() == ChatSystem::MessageType::IMAGE)
        {
            std::cout << "图片消息：" << msg.message().image_message().image_contents() << std::endl;
        }
        else if(msg.message().message_type() == ChatSystem::MessageType::FILE)
        {
            std::cout << "文件名称：" << msg.message().file_message().file_name() << std::endl;
            std::cout << "文件消息：" << msg.message().file_message().file_contents() << std::endl;
        }
        else if(msg.message().message_type() == ChatSystem::MessageType::SPEECH)
        {
            std::cout << "语音消息：" << msg.message().speech_message().speech_contents() << std::endl;
        }
        else
        {
            std::cout << "未知消息类型！" << std::endl;
        }
    }
}

TEST(消息存储子服务测试, 根据关键字进行消息搜索获取消息的测试) 
{
    auto channel = service_manager->choose(FLAGS_message_service);
    ASSERT_TRUE(channel);

    //发起Message Rpc调用
    // 2.实例化pb中的MsgStorageService_Stub类对象；
    ChatSystem::MsgStorageService_Stub stub(channel.get());
    // 3.发起rpc请求，获取响应进行处理；
    brpc::Controller cntl;
    ChatSystem::MsgSearchReq req;
    ChatSystem::MsgSearchRsp rsp;

    req.set_request_id(ChatSystem::Util::uuid());
    req.set_chat_session_id("会话ID1");
    req.set_search_key("盖");

    stub.MsgSearch(&cntl, &req, &rsp, nullptr);
    ASSERT_FALSE(cntl.Failed());
    ASSERT_TRUE(rsp.success());

    for(int i = 0; i < rsp.msg_list().size(); ++i)
    {
        auto msg = rsp.msg_list(i);
        std::cout << "------------------------根据关键字搜索获取消息----------------------------------" << std::endl;
        std::cout << msg.message_id() << std::endl;
        std::cout << msg.chat_session_id() << std::endl;
        std::cout << boost::posix_time::to_simple_string(boost::posix_time::from_time_t(msg.timestamp()))<< std::endl;
        std::cout << "user_id: "<< msg.sender().user_id() << std::endl;
        std::cout << "nickname: " << msg.sender().nickname() << std::endl;
        std::cout << "avatar: " << msg.sender().avatar() << std::endl;
        if(msg.message().message_type() == ChatSystem::MessageType::STRING)
        {
            std::cout << "文本消息：" << msg.message().string_message().content() << std::endl;
        }
        else if(msg.message().message_type() == ChatSystem::MessageType::IMAGE)
        {
            std::cout << "图片消息：" << msg.message().image_message().image_contents() << std::endl;
        }
        else if(msg.message().message_type() == ChatSystem::MessageType::FILE)
        {
            std::cout << "文件名称：" << msg.message().file_message().file_name() << std::endl;
            std::cout << "文件消息：" << msg.message().file_message().file_contents() << std::endl;
        }
        else if(msg.message().message_type() == ChatSystem::MessageType::SPEECH)
        {
            std::cout << "语音消息：" << msg.message().speech_message().speech_contents() << std::endl;
        }
        else
        {
            std::cout << "未知消息类型！" << std::endl;
        }
    }
}


int main(int argc, char* argv[])
{
    testing::InitGoogleTest(&argc, argv);
    google::ParseCommandLineFlags(&argc, &argv, true);
    ChatSystem::InitLogger(FLAGS_run_mode, FLAGS_log_file, FLAGS_log_level);

    //1. 先去注册中心进行服务的发现---发现user_server的服务器节点地址信息并实例化通信信道
    //1.1 先构造Rpc整体的服务管理信道类
    service_manager = std::make_shared<ChatSystem::ServiceManager>();
    service_manager->declared(FLAGS_message_service);  //设置需要关心的服务
    auto put_cb = std::bind(&ChatSystem::ServiceManager::onServiceOnline, service_manager.get(), std::placeholders::_1, std::placeholders::_2);
    auto del_cb = std::bind(&ChatSystem::ServiceManager::onServiceOffline, service_manager.get(), std::placeholders::_1, std::placeholders::_2);
    //1.2 构造服务发现对象 
    ChatSystem::Discovery::ptr dclient = std::make_shared<ChatSystem::Discovery>(FLAGS_etcd_host, FLAGS_base_service, put_cb, del_cb);
    

    //开始所有的单元测试
    return RUN_ALL_TESTS();
}
